home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 2
/
SPACE - Library 2 - Volume 1.iso
/
utility
/
252
/
dskpcsrc
/
program.mod
< prev
next >
Wrap
Text File
|
1988-02-13
|
22KB
|
668 lines
IMPLEMENTATION MODULE Program;
(*$S-,$T- turn off stack and range checking *)
FROM SYSTEM IMPORT ADR;
IMPORT M2Conversions;
IMPORT GEMDOS;
IMPORT GEMAESbase;
IMPORT AESGraphics;
IMPORT AESForms;
IMPORT Text;
IMPORT Icon;
IMPORT Resource;
IMPORT Screen;
IMPORT Readout;
IMPORT Float;
IMPORT Keypad;
IMPORT Expression;
IMPORT Configuration;
IMPORT Print;
IMPORT FileName;
IMPORT Disk;
TYPE String3 = ARRAY [0..2] OF CHAR;
CONST
DefaultFileName = "NONAME.CAL";
MemorySize = 500 (* steps *);
Nop = 0;
Bell = 07C;
ExecuteErrorLine1 = "[3][ The Program Counter exceeds | the length of the program. |";
ExecuteErrorLine2 = " Execution has been stopped. ][ OK ]";
FuncKeyError = "[1][ The function key | was not found. ][ OK ]";
FileSaveErrorLine1 = "[3][ An error occurred while | saving the program. Make |";
FileSaveErrorLine2 = " sure that the disk is not | full or write protected. ][ OK ]";
FileTypeError = "[3][ The file is not a valid | calculator program file. ][ OK ]";
FileLoadError = "[1][ An error occurred while | loading the program. ][ OK ]";
VAR
UpdateRegion : Screen.Box;
EnteringSteps : BOOLEAN;
PC : CARDINAL; (* Program Counter *)
Memory : ARRAY [0..MemorySize] OF INTEGER;
NumberBase : INTEGER;
ProgramSize : CARDINAL;
Index : CARDINAL;
ExpectKeys : CARDINAL;
FileSignature : String3;
Directory : Text.String80;
FileNameBody : Text.String80;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE ClearMemory;
VAR Index : CARDINAL;
BEGIN
FOR Index := 0 TO MemorySize DO
Memory[Index] := Resource.D9STOP;
END;
ProgramSize := 1;
END ClearMemory;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE GetStepText (
StepNumber : CARDINAL;
VAR Buffer : ARRAY OF CHAR );
VAR
Location : Text.String80;
Success : BOOLEAN;
Key : INTEGER;
Object : Icon.ObjectPtr;
TextPtr : Text.StringPtr;
KeyLabel : Text.String80;
BEGIN
Text.Assign ( "step ", Buffer );
M2Conversions.ConvertCardinal ( StepNumber, 3, Location );
IF Location[0] = ' ' THEN
Location[0] := '0';
END;
IF Location[1] = ' ' THEN
Location[1] := '0';
END;
Success := Text.ConcatString ( Buffer, Location, Buffer );
Success := Text.ConcatString ( Buffer, " = ", Buffer );
Key := Memory[StepNumber];
IF Key = Nop THEN
Success := Text.ConcatString ( Buffer, "Nop ", Buffer );
ELSE
Object := Icon.GetAddress ( Resource.D9CALC, Key );
TextPtr := Text.StringPtr ( Object^.Spec );
Text.Assign ( TextPtr^, KeyLabel );
Success := Text.ConcatString ( KeyLabel, " ", KeyLabel );
Success := Text.SliceString ( KeyLabel, 0, 3, KeyLabel );
Success := Text.ConcatString ( Buffer, KeyLabel, Buffer );
END;
Success := Text.ConcatChar ( Buffer, ' ', Buffer );
END GetStepText;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE InsertKey ( Key : (* IN *) INTEGER );
VAR Buffer : Text.String80;
BEGIN
Memory[PC] := Key;
IF PC >= ProgramSize THEN
INC (ProgramSize);
END;
INC (PC);
IF PC >= MemorySize THEN
GEMDOS.ConOut ( Bell );
DEC (PC); (* Cant exceed the memory capacity *)
ELSIF PC >= ProgramSize THEN
Memory[PC] := Nop;
END;
GetStepText ( PC, Buffer );
Readout.Write ( Buffer, UpdateRegion );
END InsertKey;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE ExecuteProgram;
CONST
HideKeys = FALSE;
ShowKeys = TRUE;
LeftButton = 0;
VAR
Key : INTEGER;
Number : Text.String80;
Button : INTEGER;
ExecuteMsg : ARRAY [0..200] OF CHAR;
Success : BOOLEAN;
Mouse : Screen.PixelCoordinate;
MouseState : INTEGER;
KeyboardState : INTEGER;
Object : INTEGER;
RunButton : Icon.ObjectPtr;
StopButton : Icon.ObjectPtr;
SavedNumberBase : INTEGER;
BEGIN
RunButton := Icon.GetAddress ( Resource.D9CALC, Resource.D9RUN );
RunButton^.State := RunButton^.State + {Icon.Selected};
Icon.Display ( Resource.D9CALC, Resource.D9RUN, UpdateRegion );
StopButton := Icon.GetAddress ( Resource.D9CALC, Resource.D9STOP );
StopButton^.State := StopButton^.State - {Icon.Disabled};
Icon.Display ( Resource.D9CALC, Resource.D9STOP, UpdateRegion );
AESGraphics.GrafMouse ( GEMAESbase.HourGlass, NIL );
SavedNumberBase := NumberBase;
LOOP
IF (PC >= ProgramSize) OR (PC >= MemorySize) THEN
ExecuteMsg := ExecuteErrorLine1;
Success := Text.ConcatString ( ExecuteMsg, ExecuteErrorLine2, ExecuteMsg );
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
Button := AESForms.FormAlert ( 1, ExecuteMsg );
IF (PC >= MemorySize) THEN
PC := MemorySize - 1;
END;
EXIT;
ELSE
Key := Memory[PC];
INC (PC);
IF (Key = Nop) OR
(Key = Resource.D9F1) OR
(Key = Resource.D9F2) OR
(Key = Resource.D9F3) OR
(Key = Resource.D9F4) OR
(Key = Resource.D9F5) OR
(Key = Resource.D9F6) OR
(Key = Resource.D9F7) OR
(Key = Resource.D9F8) OR
(Key = Resource.D9F9) OR
(Key = Resource.D9F10) THEN
(* do nothing *)
ELSIF Key = Resource.D9STOP THEN
EXIT;
ELSIF NOT ProcessKey ( Key, UpdateRegion ) THEN
IF Keypad.ProcessKey (
Key,
UpdateRegion,
HideKeys,
Number ) THEN
Expression.ProcessKey ( Key, UpdateRegion, Number );
IF Float.Error THEN
EXIT; (* Abort the program *)
END;
END;
END;
END;
AESGraphics.GrafMouseKeyboardState (
Mouse.X, Mouse.Y, MouseState, KeyboardState );
IF (LeftButton IN BITSET (MouseState)) AND
Icon.Find ( Resource.D9CALC, Mouse, Object ) AND
(Object = Resource.D9STOP) THEN
EXIT; (* Abort the program *)
END;
END (* LOOP *);
IF NumberBase <> SavedNumberBase THEN
Success := Keypad.ProcessKey (
NumberBase, UpdateRegion, ShowKeys, Number );
END;
RunButton^.State := RunButton^.State - {Icon.Selected};
Icon.Display ( Resource.D9CALC, Resource.D9RUN, UpdateRegion );
StopButton^.State := StopButton^.State + {Icon.Disabled};
Icon.Display ( Resource.D9CALC, Resource.D9STOP, UpdateRegion );
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
END ExecuteProgram;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE SearchKey ( Key : INTEGER );
VAR
Index : CARDINAL;
Button : INTEGER;
BEGIN
Index := 0;
LOOP
IF (Index >= ProgramSize) OR (Index >= MemorySize) THEN
Button := AESForms.FormAlert ( 1, FuncKeyError );
EXIT;
ELSIF Memory[Index] = Key THEN
PC := Index;
ExecuteProgram;
EXIT;
ELSE
INC (Index);
END;
END (* LOOP *);
END SearchKey;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE SaveProgram;
CONST
Ok = 1;
NormalFile = 0;
VAR
FullFileName : Text.String80;
ExitButton : INTEGER;
FileHandle : INTEGER;
FileStatus : INTEGER;
Count : LONGCARD;
Success : BOOLEAN;
FileSaveError : ARRAY [0..200] OF CHAR;
BEGIN
FileStatus := GEMDOS.EOK;
AESForms.FileSelectorInput (
ADR (Directory), ADR (FileNameBody), ExitButton );
Text.UpperCase ( Directory );
IF (ExitButton = Ok) AND (Text.Length (FileNameBody) > 0) THEN
FileName.BuildFileName ( Directory, FileNameBody, FullFileName );
IF FullFileName[1] = ':' THEN
Disk.CheckStatus ( ORD (FullFileName[0]) - ORD ('A') + 1 );
END;
GEMDOS.Create ( FullFileName, NormalFile, FileHandle );
IF FileHandle < GEMDOS.EOK THEN
FileStatus := FileHandle;
ELSE
FileStatus := GEMDOS.EWritF;
Count := LONGCARD (SIZE (FileSignature));
GEMDOS.Write ( FileHandle, Count, ADR (FileSignature) );
IF Count = LONGCARD (SIZE (FileSignature)) THEN
Count := LONGCARD (SIZE (ProgramSize));
GEMDOS.Write ( FileHandle, Count, ADR (ProgramSize) );
IF Count = LONGCARD (SIZE (ProgramSize)) THEN
Count := LONGCARD (SIZE (Memory));
GEMDOS.Write ( FileHandle, Count, ADR (Memory) );
IF Count = LONGCARD (SIZE (Memory)) THEN
FileStatus := GEMDOS.EOK;
END;
END;
END;
END;
Success := GEMDOS.Close ( FileHandle );
END;
IF FileStatus <> GEMDOS.EOK THEN
FileSaveError := FileSaveErrorLine1;
Success := Text.ConcatString ( FileSaveError, FileSaveErrorLine2, FileSaveError );
ExitButton := AESForms.FormAlert ( 1, FileSaveError );
END;
END SaveProgram;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE LoadProgram;
CONST
Ok = 1;
ReadWrite = 2;
VAR
Buffer : Text.String80;
FullFileName : Text.String80;
ExitButton : INTEGER;
FileHandle : INTEGER;
FileStatus : INTEGER;
Count : LONGCARD;
Success : BOOLEAN;
FileType : String3;
BEGIN
AESForms.FileSelectorInput (
ADR (Directory), ADR (FileNameBody), ExitButton );
Text.UpperCase ( Directory );
IF (ExitButton = Ok) AND (Text.Length (FileNameBody) > 0) THEN
ClearMemory;
FileName.BuildFileName ( Directory, FileNameBody, FullFileName );
IF FullFileName[1] = ':' THEN
Disk.CheckStatus ( ORD (FullFileName[0]) - ORD ('A') + 1 );
END;
FileStatus := GEMDOS.EOK;
GEMDOS.Open ( FullFileName, ReadWrite, FileHandle );
IF FileHandle < GEMDOS.EOK THEN
FileStatus := FileHandle;
ELSE
FileStatus := GEMDOS.EReadF;
Count := LONGCARD (SIZE (FileType));
GEMDOS.Read ( FileHandle, Count, ADR (FileType) );
IF Count = LONGCARD (SIZE (FileType)) THEN
IF Text.Compare ( FileType, FileSignature ) <> Text.Equal THEN
ExitButton := AESForms.FormAlert ( 1, FileTypeError );
FileStatus := GEMDOS.EOK;
ELSE
Count := LONGCARD (SIZE (ProgramSize));
GEMDOS.Read ( FileHandle, Count, ADR (ProgramSize) );
IF Count = LONGCARD (SIZE (ProgramSize)) THEN
Count := LONGCARD (SIZE (Memory));
GEMDOS.Read ( FileHandle, Count, ADR (Memory) );
IF Count = LONGCARD (SIZE (Memory)) THEN
FileStatus := GEMDOS.EOK;
END;
END;
END;
END;
END;
Success := GEMDOS.Close ( FileHandle );
IF FileStatus = GEMDOS.EOK THEN
PC := 0;
GetStepText ( PC, Buffer );
Readout.Write ( Buffer, UpdateRegion );
ELSE
ExitButton := AESForms.FormAlert ( 1, FileLoadError );
END;
END;
END LoadProgram;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE GoToAddress;
VAR NewLocation : CARDINAL;
PROCEDURE ConvertDigit ( Location : CARDINAL ) : CARDINAL;
VAR Key : INTEGER;
BEGIN
Key := Memory[Location];
IF Key = Resource.D9KEY0 THEN
RETURN (0);
ELSIF Key = Resource.D9KEY1 THEN
RETURN (1);
ELSIF Key = Resource.D9KEY2 THEN
RETURN (2);
ELSIF Key = Resource.D9KEY3 THEN
RETURN (3);
ELSIF Key = Resource.D9KEY4 THEN
RETURN (4);
ELSIF Key = Resource.D9KEY5 THEN
RETURN (5);
ELSIF Key = Resource.D9KEY6 THEN
RETURN (6);
ELSIF Key = Resource.D9KEY7 THEN
RETURN (7);
ELSIF Key = Resource.D9KEY8 THEN
RETURN (8);
ELSIF Key = Resource.D9KEY9 THEN
RETURN (9);
ELSE
RETURN (0);
END;
END ConvertDigit;
BEGIN
NewLocation :=
(ConvertDigit ( PC ) * 100) +
(ConvertDigit ( PC+1 ) * 10) +
(ConvertDigit ( PC+2 ));
NewLocation := NewLocation MOD MemorySize;
PC := NewLocation;
END GoToAddress;
(************************ LOCAL ROUTINE *****************************)
PROCEDURE PrintProgram;
VAR
Location : CARDINAL;
Buffer : Text.String80;
BEGIN
IF GEMDOS.PrnOS () THEN
FOR Location := 0 TO ProgramSize - 1 DO
GetStepText ( Location, Buffer );
Print.String ( Buffer );
END;
END;
END PrintProgram;
(********************************************************************)
PROCEDURE Initialize;
VAR
Index : CARDINAL;
Success : BOOLEAN;
BEGIN
Text.Assign ( Configuration.DefaultDrive, Directory );
Index := Text.Length (Directory);
IF (Index > 0) AND (Directory[Index - 1] = '*') THEN
Directory[Index-1] := CHR (0); (* Strip off the last asterisk *)
Success := Text.ConcatString ( Directory, "CAL", Directory );
END;
FileNameBody := DefaultFileName;
END Initialize;
(********************************************************************)
PROCEDURE ProcessKey (
VAR Key : (* IN *) INTEGER;
WindowBorders : (* IN *) Screen.Box ) : BOOLEAN;
CONST ShowKeys = TRUE;
VAR
Buffer : Text.String80;
KeyWasProcessed : BOOLEAN;
Success : BOOLEAN;
Number : Text.String80;
Status : Expression.CompareResult;
Index : CARDINAL;
Ch : CHAR;
Object : Icon.ObjectPtr;
BEGIN
UpdateRegion := WindowBorders;
KeyWasProcessed := TRUE;
IF ExpectKeys > 0 THEN
Success := Keypad.ProcessKey ( Key, UpdateRegion, ShowKeys, Number );
IF Keypad.ConvertKeyToCh ( Key, Ch ) AND (Ch >= '0') AND (Ch <= '9') THEN
InsertKey ( Key );
DEC (ExpectKeys);
ELSE
GEMDOS.ConOut ( Bell );
END;
ELSIF Key = Resource.D9PGM THEN
IF EnteringSteps THEN
EnteringSteps := FALSE;
ELSE
EnteringSteps := TRUE;
GetStepText ( PC, Buffer );
Readout.Write ( Buffer, UpdateRegion );
END;
KeyWasProcessed := FALSE;
ELSIF Key = Resource.D9SAVE THEN
SaveProgram;
ELSIF Key = Resource.D9LOAD THEN
LoadProgram;
ELSIF Key = Resource.D9GOTO THEN
IF EnteringSteps THEN
InsertKey ( Key );
ExpectKeys := 3;
Success := Keypad.ProcessKey (
Key, UpdateRegion, ShowKeys, Number );
ELSE
GoToAddress;
END;
ELSIF Key = Resource.D9EQLZER THEN
IF EnteringSteps THEN
InsertKey ( Key );
ExpectKeys := 3;
Success := Keypad.ProcessKey (
Key, UpdateRegion, ShowKeys, Number );
ELSE
Expression.CompareTOS ( Status );
IF Status = Expression.EqualZero THEN
GoToAddress;
ELSE
INC (PC, 3);
END;
END;
ELSIF Key = Resource.D9GTRZER THEN
IF EnteringSteps THEN
InsertKey ( Key );
ExpectKeys := 3;
Success := Keypad.ProcessKey (
Key, UpdateRegion, ShowKeys, Number );
ELSE
Expression.CompareTOS ( Status );
IF Status = Expression.GreaterThanZero THEN
GoToAddress;
ELSE
INC (PC, 3);
END;
END;
ELSIF Key = Resource.D9SST THEN
INC (PC);
IF PC >= ProgramSize THEN
GEMDOS.ConOut ( Bell );
PC := 0;
END;
GetStepText ( PC, Buffer );
Readout.Write ( Buffer, UpdateRegion );
ELSIF Key = Resource.D9BST THEN
IF PC = 0 THEN
GEMDOS.ConOut ( Bell );
PC := ProgramSize-1;
ELSE
DEC (PC);
END;
GetStepText ( PC, Buffer );
Readout.Write ( Buffer, UpdateRegion );
ELSIF Key = Resource.D9INS THEN
IF (ProgramSize = MemorySize) OR (PC = MemorySize-1) THEN
GEMDOS.ConOut ( Bell );
ELSE
FOR Index := (MemorySize-1) TO (PC+1) BY -1 DO
Memory[Index] := Memory[Index-1];
END;
INC (ProgramSize);
Memory[PC] := Nop;
GetStepText ( PC, Buffer );
Readout.Write ( Buffer, UpdateRegion );
END;
ELSIF Key = Resource.D9DEL THEN
IF ProgramSize = 1 THEN
GEMDOS.ConOut ( Bell );
ELSE
IF PC < (ProgramSize-1) THEN
FOR Index := (PC+1) TO (MemorySize-1) DO
Memory[Index-1] := Memory[Index];
END;
DEC (ProgramSize);
GetStepText ( PC, Buffer );
Readout.Write ( Buffer, UpdateRegion );
ELSE
GEMDOS.ConOut ( Bell );
END;
END;
ELSIF (Key = Resource.D9STO) OR
(Key = Resource.D9RCL) OR
(Key = Resource.D9SUM) THEN
IF EnteringSteps THEN
InsertKey ( Key );
ExpectKeys := 1;
Success := Keypad.ProcessKey ( Key, UpdateRegion, ShowKeys, Number );
ELSE
KeyWasProcessed := FALSE;
END;
ELSIF (Key = Resource.D9DEC) OR
(Key = Resource.D9HEX) OR
(Key = Resource.D9OCT) OR
(Key = Resource.D9BIN) THEN
NumberBase := Key;
IF EnteringSteps THEN
InsertKey ( Key );
Success := Keypad.ProcessKey ( Key, UpdateRegion, ShowKeys, Number );
ELSE
KeyWasProcessed := FALSE;
END;
ELSIF (Key = Resource.D9F1) OR
(Key = Resource.D9F2) OR
(Key = Resource.D9F3) OR
(Key = Resource.D9F4) OR
(Key = Resource.D9F5) OR
(Key = Resource.D9F6) OR
(Key = Resource.D9F7) OR
(Key = Resource.D9F8) OR
(Key = Resource.D9F9) OR
(Key = Resource.D9F10) THEN
IF EnteringSteps THEN
InsertKey ( Key );
ELSE
SearchKey ( Key );
END;
ELSIF Key = Resource.D9RUN THEN
IF NOT EnteringSteps THEN
ExecuteProgram;
END;
ELSIF Key = Resource.D9STOP THEN
IF EnteringSteps THEN
InsertKey ( Key );
END;
ELSIF Key = Resource.D9PRINT THEN
IF EnteringSteps THEN
Object := Icon.GetAddress ( Resource.D9CALC, Resource.D9PRINT );
Object^.State := Object^.State + {Icon.Selected};
Icon.Display ( Resource.D9CALC, Resource.D9PRINT, UpdateRegion );
AESGraphics.GrafMouse ( GEMAESbase.HourGlass, NIL );
PrintProgram;
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
Object^.State := Object^.State - {Icon.Selected};
Icon.Display ( Resource.D9CALC, Resource.D9PRINT, UpdateRegion );
END;
ELSE
IF EnteringSteps THEN
InsertKey ( Key );
ELSE
KeyWasProcessed := FALSE;
END;
END;
RETURN (KeyWasProcessed);
END ProcessKey;
BEGIN
ClearMemory;
EnteringSteps := FALSE;
PC := 0;
ExpectKeys := 0;
FileSignature := "SMN";
END Program.